package edu.umich.PowerTutor.ui;

import java.util.ArrayList;

import android.app.Activity;
import android.app.Dialog;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.ToggleButton;
import edu.umich.PowerTutor.R;
import edu.umich.PowerTutor.util.BatteryStats;

public class SwitchList extends Activity {
	private static final String TAG = "SwitchList";

	private BatteryStats batteryStats;
	private Runnable collector;
	private Handler handler;

	ListView switchList;
	ArrayAdapter<InfoItem> adapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// setContentView(R.layout.activity_switch_list);

		batteryStats = BatteryStats.getInstance();
		switchList = new ListView(this);

	}

	@Override
	public void onResume() {
		super.onResume();
		handler = new Handler();
		refreshView();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.switch_list, menu);
		return true;
	}

	public void refreshView() {

		adapter = new ArrayAdapter<InfoItem>(this, 0) {
			public View getView(int position, View convertView, ViewGroup parent) {
				View itemView = getLayoutInflater().inflate(
						R.layout.misc_item_layout, switchList, false);
				TextView title = (TextView) itemView.findViewById(R.id.title);
				TextView summary = (TextView) itemView
						.findViewById(R.id.summary);
				LinearLayout widgetGroup = (LinearLayout) itemView
						.findViewById(R.id.widget_frame);
				InfoItem item = (InfoItem) getItem(position);
				item.initView(title, summary, widgetGroup);
				item.setupView();
				return itemView;
			}
		};

		final ArrayList<InfoItem> allItems = new ArrayList<InfoItem>();

		allItems.add(new BatteryItem());
		allItems.add(new ScreenItem());
		allItems.add(new WifiItem());
		allItems.add(new GpsItem());
		allItems.add(new RotationItem());
		// allItems.add(new MobileDataItem());

		for (InfoItem inf : allItems) {
			adapter.add(inf);
		}

		// String count = "Count: " + adapter.getCount();
		// Log.e(TAG, count);
		// bluetooth?
		// orientation?
		// list
		switchList.setAdapter(adapter);
		setContentView(switchList);

		/*
		 * collector = new Runnable() {
		 * 
		 * @Override public void run() { BatteryItem item = (BatteryItem)
		 * allItems.get(0); item.refreshView(); } };
		 * 
		 * if (handler != null) { handler.post(collector); }
		 */

	}

	private abstract class InfoItem {
		TextView title;
		TextView summary;
		LinearLayout widgetGroup;

		public void initView(TextView title, TextView summary,
				LinearLayout widgetGroup) {
			this.title = title;
			this.summary = summary;
			this.widgetGroup = widgetGroup;
		}

		public abstract void setupView();
	}

	private class BatteryItem extends InfoItem {
		TextView txt;

		@Override
		public void setupView() {
			txt = new TextView(SwitchList.this);
			widgetGroup.addView(txt);
			double charge = batteryStats.getCharge() / 60 / 60 * 1e3;
			double perc = batteryStats.getCapacity();
			txt.setText(String.format("%1$.1f mAh\n(%2$.0f%%)", charge,
					100 * perc));
			txt.setGravity(Gravity.CENTER);
			title.setText("Battery");
			summary.setText("Battery status");
		}

		/*
		 * public void refreshView() { double charge = batteryStats.getCharge()
		 * / 60 / 60 * 1e3; double perc = batteryStats.getCapacity();
		 * txt.setText(String.format("%1$.1f mAh\n(%2$.0f%%)", charge, 100 *
		 * perc)); }
		 */
	}

	private class WifiItem extends InfoItem {
		private ToggleButton toggleButton;
		private WifiManager wifi;

		@Override
		public void setupView() {
			wifi = (WifiManager) getApplicationContext().getSystemService(
					Context.WIFI_SERVICE);
			toggleButton = new ToggleButton(SwitchList.this);
			toggleButton.setChecked(wifi.isWifiEnabled());
			toggleButton
					.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
						@Override
						public void onCheckedChanged(CompoundButton buttonView,
								boolean isChecked) {
							if (isChecked) {
								wifi.setWifiEnabled(true);
							} else {
								wifi.setWifiEnabled(false);
							}
						}
					});

			widgetGroup.addView(toggleButton);
			title.setText("Wifi");
			summary.setText("Quick turn on/off wifi here");
		}

	}

	private class GpsItem extends InfoItem {
		private ToggleButton toggleButton;

		@Override
		public void setupView() {
			toggleButton = new ToggleButton(SwitchList.this);
			toggleButton.setChecked(isGpsEnable());
			toggleButton
					.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
						@Override
						public void onCheckedChanged(CompoundButton buttonView,
								boolean isChecked) {
							toggleGps();
						}
					});

			widgetGroup.addView(toggleButton);
			title.setText("GPS");
			summary.setText("Quick turn on/off gps here");
		}

		private boolean isGpsEnable() {
			String string = Settings.Secure.getString(getContentResolver(),
					Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
			if (string != null) {
				return string.contains("gps");
			} else {
				return false;
			}
		}

		private void toggleGps() {
			Intent gpsIntent = new Intent();
			gpsIntent.setClassName("com.android.settings",
					"com.android.settings.widget.SettingsAppWidgetProvider");
			gpsIntent.addCategory("android.intent.category.ALTERNATIVE");
			gpsIntent.setData(Uri.parse("custom:3"));
			try {
				PendingIntent.getBroadcast(SwitchList.this, 0, gpsIntent, 0)
						.send();
			} catch (CanceledException e) {
				e.printStackTrace();
			}
		}
	}

	private class RotationItem extends InfoItem {
		private ToggleButton toggleButton;

		@Override
		public void setupView() {
			toggleButton = new ToggleButton(SwitchList.this);
			int flag = Settings.System.getInt(getApplicationContext()
					.getContentResolver(),
					Settings.System.ACCELEROMETER_ROTATION, 0);
			toggleButton.setChecked(flag != 0);
			toggleButton
					.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
						@Override
						public void onCheckedChanged(CompoundButton buttonView,
								boolean isChecked) {
							int flag = Settings.System.getInt(
									getApplicationContext()
											.getContentResolver(),
									Settings.System.ACCELEROMETER_ROTATION, 0);
							Settings.System.putInt(getApplicationContext()
									.getContentResolver(),
									Settings.System.ACCELEROMETER_ROTATION,
									flag == 1 ? 0 : 1);
						}
					});

			widgetGroup.addView(toggleButton);
			title.setText("Rotation");
			summary.setText("Quick turn on/off rotation here");
		}
	}

	/*
	 * private class MobileDataItem extends InfoItem { private ToggleButton
	 * toggleButton; private ConnectivityManager conn = (ConnectivityManager)
	 * getApplicationContext() .getSystemService(Context.CONNECTIVITY_SERVICE);
	 * 
	 * @Override public void setupView() { toggleButton = new
	 * ToggleButton(SwitchList.this); NetworkInfo[] infos =
	 * conn.getAllNetworkInfo(); for (NetworkInfo inf : infos) { Log.e(TAG,
	 * inf.getTypeName()); }
	 * 
	 * widgetGroup.addView(toggleButton); title.setText("Mobile Data");
	 * summary.setText("Quick turn on/off mobile data"); } }
	 */
	private class ScreenItem extends InfoItem {
		private Button setButton;

		@Override
		public void setupView() {
			setButton = new Button(SwitchList.this);
			setButton.setText("Set");
			setButton.setOnClickListener(setLis);
			widgetGroup.addView(setButton);
			title.setText("Screen");
			summary.setText("Quick set brightness");
		}

		private Dialog dialog;
		private CheckBox diaChe;
		private SeekBar diaBar;
		private Button diaOk, diaCan;

		private ScreenBrightness screenbri;
		private boolean isAuto;
		private int bri, tempBri;

		private void setDialog() {
			dialog = new Dialog(SwitchList.this);
			LayoutInflater inflater = (LayoutInflater) getApplicationContext()
					.getSystemService(LAYOUT_INFLATER_SERVICE);
			View view = inflater.inflate(R.layout.screen_item_alert_layout,
					(ViewGroup) findViewById(R.id.dialog));
			dialog.setTitle("Brightness");

			screenbri = new ScreenBrightness();
			isAuto = screenbri.isAutoBrightness();
			bri = screenbri.getBrightness();
			tempBri = 30;

			diaChe = (CheckBox) view.findViewById(R.id.brightnessauto);
			diaChe.setChecked(screenbri.isAutoBrightness());

			diaBar = (SeekBar) view.findViewById(R.id.brightnessbar);
			diaBar.setMax(225);
			diaBar.setProgress(bri - 30);
			diaBar.setOnSeekBarChangeListener(diaBarLis);

			diaOk = (Button) view.findViewById(R.id.brightnessok);
			diaOk.setText("OK");
			diaOk.setOnClickListener(diaOkLis);
			diaCan = (Button) view.findViewById(R.id.brightnesscancel);
			diaCan.setText("Cancel");
			diaCan.setOnClickListener(diaCanLis);

			dialog.setContentView(view);
		}

		private OnClickListener setLis = new OnClickListener() {
			@Override
			public void onClick(View v) {
				setDialog();
				dialog.show();
			}
		};

		private OnSeekBarChangeListener diaBarLis = new OnSeekBarChangeListener() {
			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
				screenbri.changeBrightness(progress + 30);
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
			}

			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				tempBri = seekBar.getProgress() + 30;
				screenbri.changeBrightness(tempBri);
			}

		};

		private OnClickListener diaOkLis = new OnClickListener() {
			@Override
			public void onClick(View v) {
				screenbri.setBrightness(tempBri);
				if (diaChe.isChecked()) {
					screenbri.setAutoBrightness();
				} else {
					screenbri.setManualBrightness();
				}
				dialog.dismiss();
			}
		};

		private OnClickListener diaCanLis = new OnClickListener() {
			@Override
			public void onClick(View v) {
				screenbri.setBrightness(bri);
				if (isAuto) {
					screenbri.setAutoBrightness();
				} else {
					screenbri.setManualBrightness();
				}
				dialog.dismiss();
			}
		};

		private class ScreenBrightness {
			public boolean isAutoBrightness() {
				boolean autoBri = false;
				try {
					autoBri = Settings.System.getInt(getApplicationContext()
							.getContentResolver(),
							Settings.System.SCREEN_BRIGHTNESS_MODE) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
				} catch (SettingNotFoundException e) {
					e.printStackTrace();
				}
				return autoBri;
			}

			public void setAutoBrightness() {
				Settings.System.putInt(getApplicationContext()
						.getContentResolver(),
						Settings.System.SCREEN_BRIGHTNESS_MODE,
						Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
			}

			public void setManualBrightness() {
				Settings.System.putInt(getApplicationContext()
						.getContentResolver(),
						Settings.System.SCREEN_BRIGHTNESS_MODE,
						Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
			}

			public int getBrightness() {
				int bri = 0;
				try {
					bri = Settings.System.getInt(getApplicationContext()
							.getContentResolver(),
							Settings.System.SCREEN_BRIGHTNESS);
				} catch (SettingNotFoundException e) {
					e.printStackTrace();
				}
				return bri;
			}

			public void setBrightness(int bri) {
				Uri uri = android.provider.Settings.System
						.getUriFor("screen_brightness");
				android.provider.Settings.System.putInt(getApplicationContext()
						.getContentResolver(), "screen_brightness", bri);
				getApplicationContext().getContentResolver().notifyChange(uri,
						null);
			}

			public void changeBrightness(int bri) {
				WindowManager.LayoutParams layoutP = SwitchList.this
						.getWindow().getAttributes();
				layoutP.screenBrightness = Float.valueOf(bri) * (1f / 255f);
				SwitchList.this.getWindow().setAttributes(layoutP);
			}
		}
	}

}
